home *** CD-ROM | disk | FTP | other *** search
/ Aminet 24 / Aminet 24 (1998)(GTI - Schatztruhe)[!][Apr 1998].iso / Aminet / dev / lang / PPCSmllEiffel.lha / PPCSmallEiffel / lib_se / e_feature.e < prev    next >
Text File  |  1998-01-16  |  12KB  |  463 lines

  1. --          This file is part of SmallEiffel The GNU Eiffel Compiler.
  2. --          Copyright (C) 1994-98 LORIA - UHP - CRIN - INRIA - FRANCE
  3. --            Dominique COLNET and Suzanne COLLIN - colnet@loria.fr 
  4. --                       http://www.loria.fr/SmallEiffel
  5. -- SmallEiffel is  free  software;  you can  redistribute it and/or modify it 
  6. -- under the terms of the GNU General Public License as published by the Free
  7. -- Software  Foundation;  either  version  2, or (at your option)  any  later 
  8. -- version. SmallEiffel is distributed in the hope that it will be useful,but
  9. -- WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
  10. -- or  FITNESS FOR A PARTICULAR PURPOSE.   See the GNU General Public License 
  11. -- for  more  details.  You  should  have  received a copy of the GNU General 
  12. -- Public  License  along  with  SmallEiffel;  see the file COPYING.  If not,
  13. -- write to the  Free Software Foundation, Inc., 59 Temple Place - Suite 330,
  14. -- Boston, MA 02111-1307, USA.
  15. --
  16. deferred class E_FEATURE
  17. --
  18. -- For all possible Features : procedure, function, attribute, 
  19. -- constants, once procedure, once function, ...
  20. --   
  21.  
  22. inherit GLOBALS;
  23.    
  24. feature  
  25.    
  26.    base_class: BASE_CLASS;
  27.      -- The class where the feature is really written.
  28.    
  29.    names: FEATURE_NAME_LIST; 
  30.      -- All the names of the feature.
  31.    
  32.    arguments: FORMAL_ARG_LIST is
  33.      -- Arguments if any.
  34.       deferred
  35.       end;
  36.    
  37.    result_type: TYPE;
  38.      -- Result type if any.
  39.  
  40.    header_comment: COMMENT;
  41.      -- Header comment for a routine or following comment for
  42.      -- an attribute.
  43.    
  44.    require_assertion: E_REQUIRE is
  45.      -- Not Void if any.
  46.       deferred
  47.       end;
  48.    
  49.    ensure_assertion: E_ENSURE is
  50.      -- Not Void if any.
  51.       deferred
  52.       end;
  53.  
  54.    local_vars: LOCAL_VAR_LIST;
  55.      -- Local var list if any.
  56.    
  57.    clients: CLIENT_LIST;
  58.      -- Authorized clients list of the corresponding feature
  59.      -- clause in the base definition class.
  60.    
  61.    frozen mapping_c_name_in(str: STRING) is
  62.       do
  63.      base_class.mapping_c_in(str);
  64.      str.append(first_name.to_key);
  65.       end;
  66.  
  67.    frozen mapping_c_name is
  68.       local
  69.      s: STRING;
  70.       do
  71.      s := "    ";
  72.      s.clear;
  73.      mapping_c_name_in(s);
  74.      cpp.put_string(s);
  75.       end;
  76.    
  77.    base_class_name: CLASS_NAME is
  78.      -- Name of the class where the feature is really written.
  79.       do
  80.      Result := base_class.base_class_name;
  81.       end;
  82.    
  83.    first_name: FEATURE_NAME is
  84.      -- Return the principal (first) name of the feature.
  85.       do
  86.      Result := names.item(1);
  87.       ensure
  88.      Result /= void
  89.       end; 
  90.  
  91.    start_position: POSITION is
  92.       do
  93.      Result := first_name.start_position;
  94.       end;
  95.    
  96.    to_run_feature(t: TYPE; fn: FEATURE_NAME): RUN_FEATURE is
  97.      -- If possible, gives the checked runnable feature for `t'. 
  98.      -- Note: corresponding run_class dictionary is updated
  99.      --       with this new feature.
  100.       require
  101.      t.is_run_type;
  102.      fn /= Void;
  103.       deferred
  104.       ensure
  105.      Result /= Void implies t.run_class.at(fn) = Result;
  106.      Result = Void implies nb_errors > 0
  107.       end;
  108.    
  109.    is_exported_to(c: BASE_CLASS): BOOLEAN is
  110.       do
  111.      Result := clients.gives_permission_to(c.base_class_name);
  112.       end;
  113.    
  114.    is_deferred: BOOLEAN is do end;
  115.    
  116.    is_merge_with(other: E_FEATURE; rc: RUN_CLASS): BOOLEAN is
  117.      -- True when headings of Current can be merge with heading 
  118.      -- of `other' in `rc'.
  119.       require
  120.      Current /= other;
  121.       do
  122.      if result_type /= other.result_type then
  123.         if result_type = Void or else other.result_type = Void then
  124.            eh.add_position(other.start_position);
  125.            error(start_position,"One has Result but not the other.");
  126.         end;
  127.      end;
  128.      if arguments /= other.arguments then
  129.         if arguments = Void or else other.arguments = Void then
  130.            eh.add_position(other.start_position);
  131.            error(start_position,"One has argument(s) but not the other.");
  132.         elseif arguments.count /= other.arguments.count then 
  133.            eh.add_position(other.start_position);
  134.            error(start_position,"Incompatible number of arguments.");
  135.         end;
  136.      end;
  137.      if result_type /= Void then
  138.         if not result_type.is_a_in(other.result_type,rc) then
  139.            eh.error(em1);
  140.         end;
  141.      end;
  142.      if arguments /= Void then
  143.         if not arguments.is_a_in(other.arguments,rc) then
  144.            eh.add_position(other.start_position);
  145.            error(start_position,em1);
  146.         end;
  147.      end;
  148.      Result := nb_errors = 0; 
  149.       end;
  150.    
  151.    can_hide(other: E_FEATURE; rc: RUN_CLASS): BOOLEAN is
  152.      -- True when headings of Current can be hide with
  153.      -- heading of `other' in `rc'.
  154.       require
  155.      Current /= other;
  156.       do
  157.      if result_type /= other.result_type then
  158.         if result_type = Void or else other.result_type = Void then
  159.            eh.add_position(other.start_position);
  160.            error(start_position,"One has Result but not the other.");
  161.         end;
  162.      end;
  163.      if arguments /= other.arguments then
  164.         if arguments = Void or else other.arguments = Void then
  165.            eh.add_position(other.start_position);
  166.            error(start_position,"One has argument(s) but not the other.");
  167.         elseif arguments.count /= other.arguments.count then 
  168.            eh.add_position(other.start_position);
  169.            error(start_position,"Incompatible number of arguments.");
  170.         end;
  171.      end;
  172.      if nb_errors = 0 then
  173.         if result_type /= Void then
  174.            if not result_type.is_a_in(other.result_type,rc) then
  175.           eh.append(em2);
  176.           eh.append(rc.current_type.run_time_mark);
  177.           eh.error(fz_dot);
  178.            end;
  179.         end;
  180.      end;
  181.      if nb_errors = 0 then
  182.         if arguments /= Void then
  183.            if not arguments.is_a_in(other.arguments,rc) then
  184.           eh.add_position(other.start_position);
  185.           eh.add_position(start_position)
  186.           eh.append(em2);
  187.           eh.append(rc.current_type.run_time_mark);
  188.           eh.error(fz_dot);
  189.            end;
  190.         end;
  191.      end;
  192.      Result := nb_errors = 0; 
  193.       end;
  194.  
  195. feature {PARENT}
  196.  
  197.    frozen try_to_undefine(fn: FEATURE_NAME; 
  198.               bc: BASE_CLASS): DEFERRED_ROUTINE is
  199.      -- When class `bc' has an undefine clause for `fn'.
  200.      -- Compute the corresponding undefined feature.
  201.      -- Check for (VDUS).
  202.      -- Not Void when no errors.
  203.       require
  204.      fn /= Void;
  205.      bc.base_class_name.is_subclass_of(base_class_name)
  206.       do
  207.      fn.undefine_in(bc);
  208.      Result := try_to_undefine_aux(fn,bc);
  209.      if Result /= Void then
  210.         Result.set_clients(clients);
  211.      else
  212.         bc.fatal_undefine(fn);
  213.      end;
  214.       ensure
  215.      Result /= Void
  216.       end;
  217.    
  218. feature {FEATURE_CLAUSE,E_FEATURE}
  219.    
  220.    set_clients(c: like clients) is
  221.       require
  222.      c /= Void;
  223.       do
  224.      clients := c;
  225.       ensure
  226.      clients = c;
  227.       end;
  228.    
  229. feature 
  230.    
  231.    set_header_comment(hc: like header_comment) is
  232.       do
  233.      header_comment := hc;
  234.       end;
  235.    
  236. feature -- Pretty printing :
  237.    
  238.    pretty_print is
  239.       require
  240.      fmt.indent_level = 1;
  241.       deferred
  242.       ensure
  243.      fmt.indent_level = 1;
  244.       end;
  245.    
  246.    frozen pretty_print_profile is
  247.       do
  248.      pretty_print_names;
  249.      fmt.set_indent_level(2);
  250.      pretty_print_arguments;
  251.      fmt.set_indent_level(3);
  252.      if result_type /= Void then
  253.         fmt.put_string(": ");
  254.         result_type.pretty_print;
  255.      end;
  256.       end;
  257.    
  258. feature {RUN_FEATURE}
  259.    
  260.    run_require(rf: RUN_FEATURE): RUN_REQUIRE is
  261.      -- Collect all (inherited) require assertions for 
  262.      -- `rf'. Unless return Void (no assertion at all).
  263.       require
  264.      rf /= Void;
  265.      rf.base_feature = Current;
  266.       local
  267.      i: INTEGER;
  268.      r: like runnable;
  269.      er: E_REQUIRE;
  270.      hc: COMMENT;
  271.      ar: ARRAY[E_REQUIRE];
  272.  
  273.       do
  274.      require_collector.clear;
  275.      rf.current_type.base_class.collect_for(code_require,rf.name);
  276.      if not require_collector.empty then
  277.         from  
  278.            i := 1;
  279.         until
  280.            i > require_collector.upper
  281.         loop
  282.            er := require_collector.item(i);
  283.            hc := er.header_comment;
  284.            if not er.empty then
  285.           r := runnable(er.list,rf.current_type,rf);
  286.           if r /= Void then
  287.              !!er.from_runnable(r);
  288.              er.set_header_comment(hc);
  289.              if ar = Void then
  290.             ar := <<er>>;
  291.              else
  292.             ar.add_last(er);
  293.              end;
  294.           end;
  295.            end;
  296.            i := i + 1;
  297.         end;        
  298.         if ar /= Void then
  299.            !!Result.make(ar);
  300.         end;
  301.      end;
  302.       end;
  303.    
  304.    run_ensure(rf: RUN_FEATURE): E_ENSURE is
  305.       require
  306.      rf /= Void;
  307.      rf.base_feature = Curre